﻿using Service.Repository;
using SqlSugar;
using System.Linq.Expressions;

namespace Service.Core.Repository
{
    public interface IRepository<TEntity>
        where TEntity : Entity
    {

        ISqlSugarClient Db { get; }
        //DbContext _dbContext { get; }

        /// <summary>
        /// 获取总条数
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<int> GetCount(Expression<Func<TEntity, bool>> whereExpression = null,
            CancellationToken cancellationToken = default);


        /// <summary>
        /// 获取最大值
        /// </summary>
        /// <param name="MaxExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<int> GetMaxAsync(Expression<Func<TEntity, int>> maxExpression,
            Expression<Func<TEntity, bool>> whereExpression = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取最大值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="maxExpression"></param>
        /// <param name="whereExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<TResult> GetMaxAsync<TResult>(Expression<Func<TEntity, TResult>> maxExpression,
    Expression<Func<TEntity, bool>>? whereExpression = null,
    CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="selectExpression"></param>
        /// <param name="whereExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<List<TResult>> GetListSelectResultAsync<TResult>(Expression<Func<TEntity, TResult>> selectExpression,
            Expression<Func<TEntity, bool>> whereExpression = null,
            Expression<Func<TEntity, object>>? orderExpression = null,
            OrderByType orderByType = OrderByType.Asc,
            CancellationToken cancellationToken = default);


        Task<TResult> GetSeleteFirstAsync<TResult>(Expression<Func<TEntity, Boolean>> whereExpression,
            Expression<Func<TEntity, TResult>> selectExpression, CancellationToken cancellationToken = default);

        Task<TEntity> GetByIdAsync(object id, CancellationToken cancellationToken = default);

        Task<List<TResult>> GetListAsync<T, TResult>(Expression<Func<T, Boolean>> whereExpression,
            Expression<Func<T, TResult>> selectExpression);


        /// <summary>
        /// /分页获取列表
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalNumber"></param>
        /// <param name="selectExpression"></param>
        /// <param name="whereExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<List<TResult>> GetPagesListReturnTResult<TResult>(int pageIndex, int pageSize,
            RefAsync<int> totalNumber,
            Expression<Func<TEntity, TResult>> selectExpression,
            Expression<Func<TEntity, bool>>? whereExpression = null,
            Expression<Func<TEntity, object>>? orderExpression = null,
            OrderByType orderByType = OrderByType.Asc,
            CancellationToken cancellationToken = default);


        /// <summary>
        /// /分页获取列表
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalNumber"></param>
        /// <param name="whereExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<List<TEntity>> GetPagesList(int pageIndex, int pageSize, RefAsync<int> totalNumber,
            Expression<Func<TEntity, bool>> whereExpression = null,
            Expression<Func<TEntity, object>>? orderExpression = null,
            OrderByType orderByType = OrderByType.Asc, CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> whereExpression = null,
            Expression<Func<TEntity, object>>? orderExpression = null,
            OrderByType orderByType = OrderByType.Asc,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据条件获取单条数据
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression,
            CancellationToken cancellationToken = default);

        Task<bool> AnyAsync(Expression<Func<TEntity, bool>> whereExpression,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 新增一条数据
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> InsertAsync(TEntity entity, CancellationToken cancellationToken = default);


        /// <summary>
        /// 新增多条数据
        /// </summary>
        /// <param name="entitys"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> InsertRangeAsync(List<TEntity> entitys, CancellationToken cancellationToken = default);


        /// <summary>
        /// 物理删除一条数据
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);


        Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression, CancellationToken cancellationToken = default);



        /// <summary>
        /// 物理删除多条数据
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> DeleteRangeAsync(List<TEntity> entitys, CancellationToken cancellationToken = default);


        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);


        /// <summary>
        /// 修改，乐观锁
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> UpdateWithoptLockAsync(TEntity entity, CancellationToken cancellationToken = default);


        /// <summary>
        /// 修改多条数据
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> UpdateRangeAsync(List<TEntity> entitys, CancellationToken cancellationToken = default);


        /// <summary>
        /// 修改指定字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="columns"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> UpdateColumnsAsync(TEntity entity, Expression<Func<TEntity, object>> columns,
            CancellationToken cancellationToken = default);


        /// <summary>
        /// 修改指定字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="columns"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> UpdateColumnsRangeAsync(List<TEntity> entity, Expression<Func<TEntity, object>> columns,
            CancellationToken cancellationToken = default);
    }

    public interface IRepository<TEntity, TKey> : IRepository<TEntity>
        where TEntity : Entity<TKey>
    {
        Task<bool> SoftDeleteAsync(TEntity entity, CancellationToken cancellationToken = default);
        Task<bool> SoftDeleteRangeAsync(List<TEntity> entitys, CancellationToken cancellationToken = default);
        Task<TEntity> GetByIdAsync(TKey id, CancellationToken cancellationToken = default);
    }
}